'use strict';
var d = Object.defineProperty;
var p = (n, e, t) =>
  e in n
    ? d(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t })
    : (n[e] = t);
var h = (n, e, t) => (p(n, typeof e != 'symbol' ? e + '' : e, t), t);
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const u = require('./cst.cjs');
function l(n) {
  switch (n) {
    case void 0:
    case ' ':
    case `
`:
    case '\r':
    case '	':
      return !0;
    default:
      return !1;
  }
}
const o = '0123456789ABCDEFabcdef'.split(''),
  b =
    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()".split(
      '',
    ),
  f = ',[]{}'.split(''),
  y = ` ,[]{}
\r	`.split(''),
  c = n => !n || y.includes(n);
class w {
  constructor() {
    h(this, 'atEnd', !1);
    h(this, 'blockScalarIndent', -1);
    h(this, 'blockScalarKeep', !1);
    h(this, 'buffer', '');
    h(this, 'flowKey', !1);
    h(this, 'flowLevel', 0);
    h(this, 'indentNext', 0);
    h(this, 'indentValue', 0);
    h(this, 'lineEndPos', null);
    h(this, 'next', null);
    h(this, 'pos', 0);
  }
  *lex(e, t = !1) {
    e &&
      ((this.buffer = this.buffer ? this.buffer + e : e),
      (this.lineEndPos = null)),
      (this.atEnd = !t);
    let s = this.next ?? 'stream';
    for (; s && (t || this.hasChars(1)); ) s = yield* this.parseNext(s);
  }
  atLineEnd() {
    let e = this.pos,
      t = this.buffer[e];
    for (; t === ' ' || t === '	'; ) t = this.buffer[++e];
    return !t ||
      t === '#' ||
      t ===
        `
`
      ? !0
      : t === '\r'
        ? this.buffer[e + 1] ===
          `
`
        : !1;
  }
  charAt(e) {
    return this.buffer[this.pos + e];
  }
  continueScalar(e) {
    let t = this.buffer[e];
    if (this.indentNext > 0) {
      let s = 0;
      for (; t === ' '; ) t = this.buffer[++s + e];
      if (t === '\r') {
        const i = this.buffer[s + e + 1];
        if (
          i ===
            `
` ||
          (!i && !this.atEnd)
        )
          return e + s + 1;
      }
      return t ===
        `
` ||
        s >= this.indentNext ||
        (!t && !this.atEnd)
        ? e + s
        : -1;
    }
    if (t === '-' || t === '.') {
      const s = this.buffer.substr(e, 3);
      if ((s === '---' || s === '...') && l(this.buffer[e + 3])) return -1;
    }
    return e;
  }
  getLine() {
    let e = this.lineEndPos;
    return (
      (typeof e != 'number' || (e !== -1 && e < this.pos)) &&
        ((e = this.buffer.indexOf(
          `
`,
          this.pos,
        )),
        (this.lineEndPos = e)),
      e === -1
        ? this.atEnd
          ? this.buffer.substring(this.pos)
          : null
        : (this.buffer[e - 1] === '\r' && (e -= 1),
          this.buffer.substring(this.pos, e))
    );
  }
  hasChars(e) {
    return this.pos + e <= this.buffer.length;
  }
  setNext(e) {
    return (
      (this.buffer = this.buffer.substring(this.pos)),
      (this.pos = 0),
      (this.lineEndPos = null),
      (this.next = e),
      null
    );
  }
  peek(e) {
    return this.buffer.substr(this.pos, e);
  }
  *parseNext(e) {
    switch (e) {
      case 'stream':
        return yield* this.parseStream();
      case 'line-start':
        return yield* this.parseLineStart();
      case 'block-start':
        return yield* this.parseBlockStart();
      case 'doc':
        return yield* this.parseDocument();
      case 'flow':
        return yield* this.parseFlowCollection();
      case 'quoted-scalar':
        return yield* this.parseQuotedScalar();
      case 'block-scalar':
        return yield* this.parseBlockScalar();
      case 'plain-scalar':
        return yield* this.parsePlainScalar();
    }
  }
  *parseStream() {
    let e = this.getLine();
    if (e === null) return this.setNext('stream');
    if (
      (e[0] === u.BOM && (yield* this.pushCount(1), (e = e.substring(1))),
      e[0] === '%')
    ) {
      let t = e.length;
      const s = e.indexOf('#');
      if (s !== -1) {
        const r = e[s - 1];
        (r === ' ' || r === '	') && (t = s - 1);
      }
      for (;;) {
        const r = e[t - 1];
        if (r === ' ' || r === '	') t -= 1;
        else break;
      }
      const i = (yield* this.pushCount(t)) + (yield* this.pushSpaces(!0));
      return yield* this.pushCount(e.length - i), this.pushNewline(), 'stream';
    }
    if (this.atLineEnd()) {
      const t = yield* this.pushSpaces(!0);
      return (
        yield* this.pushCount(e.length - t), yield* this.pushNewline(), 'stream'
      );
    }
    return yield u.DOCUMENT, yield* this.parseLineStart();
  }
  *parseLineStart() {
    const e = this.charAt(0);
    if (!e && !this.atEnd) return this.setNext('line-start');
    if (e === '-' || e === '.') {
      if (!this.atEnd && !this.hasChars(4)) return this.setNext('line-start');
      const t = this.peek(3);
      if (t === '---' && l(this.charAt(3)))
        return (
          yield* this.pushCount(3),
          (this.indentValue = 0),
          (this.indentNext = 0),
          'doc'
        );
      if (t === '...' && l(this.charAt(3)))
        return yield* this.pushCount(3), 'stream';
    }
    return (
      (this.indentValue = yield* this.pushSpaces(!1)),
      this.indentNext > this.indentValue &&
        !l(this.charAt(1)) &&
        (this.indentNext = this.indentValue),
      yield* this.parseBlockStart()
    );
  }
  *parseBlockStart() {
    const [e, t] = this.peek(2);
    if (!t && !this.atEnd) return this.setNext('block-start');
    if ((e === '-' || e === '?' || e === ':') && l(t)) {
      const s = (yield* this.pushCount(1)) + (yield* this.pushSpaces(!0));
      return (
        (this.indentNext = this.indentValue + 1),
        (this.indentValue += s),
        yield* this.parseBlockStart()
      );
    }
    return 'doc';
  }
  *parseDocument() {
    yield* this.pushSpaces(!0);
    const e = this.getLine();
    if (e === null) return this.setNext('doc');
    let t = yield* this.pushIndicators();
    switch (e[t]) {
      case '#':
        yield* this.pushCount(e.length - t);
      case void 0:
        return yield* this.pushNewline(), yield* this.parseLineStart();
      case '{':
      case '[':
        return (
          yield* this.pushCount(1),
          (this.flowKey = !1),
          (this.flowLevel = 1),
          'flow'
        );
      case '}':
      case ']':
        return yield* this.pushCount(1), 'doc';
      case '*':
        return yield* this.pushUntil(c), 'doc';
      case '"':
      case "'":
        return yield* this.parseQuotedScalar();
      case '|':
      case '>':
        return (
          (t += yield* this.parseBlockScalarHeader()),
          (t += yield* this.pushSpaces(!0)),
          yield* this.pushCount(e.length - t),
          yield* this.pushNewline(),
          yield* this.parseBlockScalar()
        );
      default:
        return yield* this.parsePlainScalar();
    }
  }
  *parseFlowCollection() {
    let e,
      t,
      s = -1;
    do
      (e = yield* this.pushNewline()),
        e > 0
          ? ((t = yield* this.pushSpaces(!1)), (this.indentValue = s = t))
          : (t = 0),
        (t += yield* this.pushSpaces(!0));
    while (e + t > 0);
    const i = this.getLine();
    if (i === null) return this.setNext('flow');
    if (
      ((s !== -1 && s < this.indentNext && i[0] !== '#') ||
        (s === 0 && (i.startsWith('---') || i.startsWith('...')) && l(i[3]))) &&
      !(
        s === this.indentNext - 1 &&
        this.flowLevel === 1 &&
        (i[0] === ']' || i[0] === '}')
      )
    )
      return (
        (this.flowLevel = 0), yield u.FLOW_END, yield* this.parseLineStart()
      );
    let r = 0;
    for (; i[r] === ','; )
      (r += yield* this.pushCount(1)),
        (r += yield* this.pushSpaces(!0)),
        (this.flowKey = !1);
    switch (((r += yield* this.pushIndicators()), i[r])) {
      case void 0:
        return 'flow';
      case '#':
        return yield* this.pushCount(i.length - r), 'flow';
      case '{':
      case '[':
        return (
          yield* this.pushCount(1),
          (this.flowKey = !1),
          (this.flowLevel += 1),
          'flow'
        );
      case '}':
      case ']':
        return (
          yield* this.pushCount(1),
          (this.flowKey = !0),
          (this.flowLevel -= 1),
          this.flowLevel ? 'flow' : 'doc'
        );
      case '*':
        return yield* this.pushUntil(c), 'flow';
      case '"':
      case "'":
        return (this.flowKey = !0), yield* this.parseQuotedScalar();
      case ':': {
        const a = this.charAt(1);
        if (this.flowKey || l(a) || a === ',')
          return (
            (this.flowKey = !1),
            yield* this.pushCount(1),
            yield* this.pushSpaces(!0),
            'flow'
          );
      }
      default:
        return (this.flowKey = !1), yield* this.parsePlainScalar();
    }
  }
  *parseQuotedScalar() {
    const e = this.charAt(0);
    let t = this.buffer.indexOf(e, this.pos + 1);
    if (e === "'")
      for (; t !== -1 && this.buffer[t + 1] === "'"; )
        t = this.buffer.indexOf("'", t + 2);
    else
      for (; t !== -1; ) {
        let r = 0;
        for (; this.buffer[t - 1 - r] === '\\'; ) r += 1;
        if (r % 2 === 0) break;
        t = this.buffer.indexOf('"', t + 1);
      }
    const s = this.buffer.substring(0, t);
    let i = s.indexOf(
      `
`,
      this.pos,
    );
    if (i !== -1) {
      for (; i !== -1; ) {
        const r = this.continueScalar(i + 1);
        if (r === -1) break;
        i = s.indexOf(
          `
`,
          r,
        );
      }
      i !== -1 && (t = i - (s[i - 1] === '\r' ? 2 : 1));
    }
    if (t === -1) {
      if (!this.atEnd) return this.setNext('quoted-scalar');
      t = this.buffer.length;
    }
    return yield* this.pushToIndex(t + 1, !1), this.flowLevel ? 'flow' : 'doc';
  }
  *parseBlockScalarHeader() {
    (this.blockScalarIndent = -1), (this.blockScalarKeep = !1);
    let e = this.pos;
    for (;;) {
      const t = this.buffer[++e];
      if (t === '+') this.blockScalarKeep = !0;
      else if (t > '0' && t <= '9') this.blockScalarIndent = Number(t) - 1;
      else if (t !== '-') break;
    }
    return yield* this.pushUntil(t => l(t) || t === '#');
  }
  *parseBlockScalar() {
    let e = this.pos - 1,
      t = 0,
      s;
    e: for (let i = this.pos; (s = this.buffer[i]); ++i)
      switch (s) {
        case ' ':
          t += 1;
          break;
        case `
`:
          (e = i), (t = 0);
          break;
        case '\r': {
          const r = this.buffer[i + 1];
          if (!r && !this.atEnd) return this.setNext('block-scalar');
          if (
            r ===
            `
`
          )
            break;
        }
        default:
          break e;
      }
    if (!s && !this.atEnd) return this.setNext('block-scalar');
    if (t >= this.indentNext) {
      this.blockScalarIndent === -1
        ? (this.indentNext = t)
        : (this.indentNext += this.blockScalarIndent);
      do {
        const i = this.continueScalar(e + 1);
        if (i === -1) break;
        e = this.buffer.indexOf(
          `
`,
          i,
        );
      } while (e !== -1);
      if (e === -1) {
        if (!this.atEnd) return this.setNext('block-scalar');
        e = this.buffer.length;
      }
    }
    if (!this.blockScalarKeep)
      do {
        let i = e - 1,
          r = this.buffer[i];
        r === '\r' && (r = this.buffer[--i]);
        const a = i;
        for (; r === ' ' || r === '	'; ) r = this.buffer[--i];
        if (
          r ===
            `
` &&
          i >= this.pos &&
          i + 1 + t > a
        )
          e = i;
        else break;
      } while (!0);
    return (
      yield u.SCALAR,
      yield* this.pushToIndex(e + 1, !0),
      yield* this.parseLineStart()
    );
  }
  *parsePlainScalar() {
    const e = this.flowLevel > 0;
    let t = this.pos - 1,
      s = this.pos - 1,
      i;
    for (; (i = this.buffer[++s]); )
      if (i === ':') {
        const r = this.buffer[s + 1];
        if (l(r) || (e && r === ',')) break;
        t = s;
      } else if (l(i)) {
        let r = this.buffer[s + 1];
        if (
          (i === '\r' &&
            (r ===
            `
`
              ? ((s += 1),
                (i = `
`),
                (r = this.buffer[s + 1]))
              : (t = s)),
          r === '#' || (e && f.includes(r)))
        )
          break;
        if (
          i ===
          `
`
        ) {
          const a = this.continueScalar(s + 1);
          if (a === -1) break;
          s = Math.max(s, a - 2);
        }
      } else {
        if (e && f.includes(i)) break;
        t = s;
      }
    return !i && !this.atEnd
      ? this.setNext('plain-scalar')
      : (yield u.SCALAR,
        yield* this.pushToIndex(t + 1, !0),
        e ? 'flow' : 'doc');
  }
  *pushCount(e) {
    return e > 0
      ? (yield this.buffer.substr(this.pos, e), (this.pos += e), e)
      : 0;
  }
  *pushToIndex(e, t) {
    const s = this.buffer.slice(this.pos, e);
    return s
      ? (yield s, (this.pos += s.length), s.length)
      : (t && (yield ''), 0);
  }
  *pushIndicators() {
    switch (this.charAt(0)) {
      case '!':
        return (
          (yield* this.pushTag()) +
          (yield* this.pushSpaces(!0)) +
          (yield* this.pushIndicators())
        );
      case '&':
        return (
          (yield* this.pushUntil(c)) +
          (yield* this.pushSpaces(!0)) +
          (yield* this.pushIndicators())
        );
      case '-':
      case '?':
      case ':': {
        const e = this.flowLevel > 0,
          t = this.charAt(1);
        if (l(t) || (e && f.includes(t)))
          return (
            e
              ? this.flowKey && (this.flowKey = !1)
              : (this.indentNext = this.indentValue + 1),
            (yield* this.pushCount(1)) +
              (yield* this.pushSpaces(!0)) +
              (yield* this.pushIndicators())
          );
      }
    }
    return 0;
  }
  *pushTag() {
    if (this.charAt(1) === '<') {
      let e = this.pos + 2,
        t = this.buffer[e];
      for (; !l(t) && t !== '>'; ) t = this.buffer[++e];
      return yield* this.pushToIndex(t === '>' ? e + 1 : e, !1);
    } else {
      let e = this.pos + 1,
        t = this.buffer[e];
      for (; t; )
        if (b.includes(t)) t = this.buffer[++e];
        else if (
          t === '%' &&
          o.includes(this.buffer[e + 1]) &&
          o.includes(this.buffer[e + 2])
        )
          t = this.buffer[(e += 3)];
        else break;
      return yield* this.pushToIndex(e, !1);
    }
  }
  *pushNewline() {
    const e = this.buffer[this.pos];
    return e ===
      `
`
      ? yield* this.pushCount(1)
      : e === '\r' &&
          this.charAt(1) ===
            `
`
        ? yield* this.pushCount(2)
        : 0;
  }
  *pushSpaces(e) {
    let t = this.pos - 1,
      s;
    do s = this.buffer[++t];
    while (s === ' ' || (e && s === '	'));
    const i = t - this.pos;
    return i > 0 && (yield this.buffer.substr(this.pos, i), (this.pos = t)), i;
  }
  *pushUntil(e) {
    let t = this.pos,
      s = this.buffer[t];
    for (; !e(s); ) s = this.buffer[++t];
    return yield* this.pushToIndex(t, !1);
  }
}
exports.Lexer = w;
